package student;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

@WebServlet("/StudentDashboardDataServlet")
public class StudentDashboardDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(false);
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        Map<String, Object> jsonResponse = new LinkedHashMap<>();

        if (session == null || session.getAttribute("student_id") == null) {
            jsonResponse.put("success", false);
            jsonResponse.put("code", 401);
            jsonResponse.put("message", "会话已过期，请重新登录");
            out.print(enhancedMapToJson(jsonResponse));
            return;
        }

        Integer studentId = (Integer) session.getAttribute("student_id");
        Integer classId = (Integer) session.getAttribute("class_id");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

        try {
            Connectmysql conn = new Connectmysql(
                    "jdbc:mysql://localhost:3306/exam",
                    "root", "root", "com.mysql.cj.jdbc.Driver");

            if (conn.open()) {
                // 获取已参加考试数量
                String examCountSql = "SELECT COUNT(DISTINCT exam_id) AS exam_count FROM student_score WHERE student_id = ?";
                ResultSet rs = conn.executeSql(examCountSql, new Object[]{studentId});
                int examCount = rs.next() ? rs.getInt("exam_count") : 0;

                // 获取通过课程数量
                String passedSql = "SELECT COUNT(DISTINCT course_id) AS passed_count FROM student_score " +
                        "WHERE student_id = ? AND is_passed = 1";
                rs = conn.executeSql(passedSql, new Object[]{studentId});
                int passedCount = rs.next() ? rs.getInt("passed_count") : 0;

                // 获取未通过课程数量
                String failedSql = "SELECT COUNT(DISTINCT course_id) AS failed_count FROM student_score " +
                        "WHERE student_id = ? AND is_passed = 0";
                rs = conn.executeSql(failedSql, new Object[]{studentId});
                int failedCount = rs.next() ? rs.getInt("failed_count") : 0;

                // 获取平均分
                String avgSql = "SELECT AVG(score) AS avg_score FROM student_score WHERE student_id = ?";
                rs = conn.executeSql(avgSql, new Object[]{studentId});
                double avgScore = rs.next() ? rs.getDouble("avg_score") : 0;

                // 获取近期考试
                String recentExamsSql = "SELECT e.exam_id, e.exam_name, c.course_name, e.start_time, e.duration, e.status " +
                        "FROM exam e JOIN course c ON e.course_id = c.course_id " +
                        "JOIN exam_class ec ON e.exam_id = ec.exam_id " +
                        "WHERE ec.class_id = ? " +
                        "ORDER BY e.start_time DESC LIMIT 5";
                rs = conn.executeSql(recentExamsSql, new Object[]{classId});
                List<Map<String, Object>> recentExams = new ArrayList<>();

                while (rs.next()) {
                    Map<String, Object> exam = new LinkedHashMap<>();
                    exam.put("exam_id", rs.getInt("exam_id"));
                    exam.put("exam_name", rs.getString("exam_name")); // 不在数据库层面转义
                    exam.put("course_name", rs.getString("course_name"));

                    // 格式化时间并处理空值
                    Timestamp startTime = rs.getTimestamp("start_time");
                    if (startTime != null) {
                        exam.put("start_time", sdf.format(startTime));
                    } else {
                        exam.put("start_time", null); // 使用null而不是"N/A"
                    }

                    exam.put("duration", rs.getInt("duration"));
                    exam.put("status", rs.getInt("status"));
                    recentExams.add(exam);
                }

                jsonResponse.put("success", true);
                jsonResponse.put("examCount", examCount);
                jsonResponse.put("passedCount", passedCount);
                jsonResponse.put("failedCount", failedCount);
                jsonResponse.put("averageScore", Math.round(avgScore * 100) / 100.0);
                jsonResponse.put("recentExams", recentExams);
            }
        } catch (Exception e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "加载仪表盘数据失败: " + e.getMessage());
        } finally {
            out.print(enhancedMapToJson(jsonResponse));
            out.flush();
        }
    }

    // 增强的JSON序列化方法
    private String enhancedMapToJson(Map<String, Object> map) {
        StringBuilder json = new StringBuilder("{");
        boolean first = true;

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (!first) {
                json.append(",");
            }
            first = false;

            json.append("\"").append(escapeJson(entry.getKey())).append("\":");

            Object value = entry.getValue();
            json.append(toJsonValue(value));
        }

        json.append("}");
        return json.toString();
    }

    // 将任意值转换为JSON字符串
    private String toJsonValue(Object value) {
        if (value == null) {
            return "null";
        } else if (value instanceof String) {
            return "\"" + escapeJson((String) value) + "\"";
        } else if (value instanceof Boolean) {
            return value.toString();
        } else if (value instanceof Number) {
            return value.toString();
        } else if (value instanceof Map) {
            return enhancedMapToJson((Map<String, Object>) value);
        } else if (value instanceof List) {
            return listToJson((List<?>) value);
        } else {
            // 其他类型转为字符串并转义
            return "\"" + escapeJson(value.toString()) + "\"";
        }
    }

    // 处理列表的JSON序列化
    private String listToJson(List<?> list) {
        StringBuilder json = new StringBuilder("[");
        boolean first = true;

        for (Object item : list) {
            if (!first) {
                json.append(",");
            }
            first = false;

            json.append(toJsonValue(item));
        }

        json.append("]");
        return json.toString();
    }

    // 增强转义处理
    private String escapeJson(String input) {
        if (input == null) return "";

        StringBuilder escaped = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            switch (c) {
                case '\\': escaped.append("\\\\"); break;
                case '\"': escaped.append("\\\""); break;
                case '\b': escaped.append("\\b"); break;
                case '\f': escaped.append("\\f"); break;
                case '\n': escaped.append("\\n"); break;
                case '\r': escaped.append("\\r"); break;
                case '\t': escaped.append("\\t"); break;
                case '/': escaped.append("\\/"); break;
                default:
                    // 移除非法的控制字符 (U+0000 到 U+001F)
                    if (c >= 0x0000 && c <= 0x001F) {
                        // 忽略或替换为空字符串
                    } else {
                        escaped.append(c);
                    }
                    break;
            }
        }

        return escaped.toString();
    }
}